﻿using System;
using System.Xml;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;
using CID.Domain.Exceptions;

namespace CID.Domain.Tests.Infrastructure.ParameterValue
{
    public abstract class BaseParameterValueTests : BaseFunctionalTests
    {
        protected const string StringValue = "String Value";
        protected const int IntegerValue = 321;
        protected const decimal DecimalValue = 3.21m;
        protected static readonly DateTime DateTimeValue = DateTime.Now;
        protected const bool BooleanValue = false;
        protected static readonly Guid UniqueIdentifierValue = Guid.NewGuid();
        protected const string XmlValueAsString = "<?xml version=\"1.0\"?><configuration><connectionStrings><add name=\"\" connectionString=\"\" providerName=\"System.Data.SqlClient\" /></connectionStrings></configuration>";


        protected IParameterValue ParameterValue { get; private set; }
        protected string stringValue;
        protected int integerValue;
        protected decimal decimalValue;
        protected DateTime dateTimeValue;
        protected bool booleanValue;
        protected Guid uniqueIdentifierValue;
        protected string xmlValueAsString;

        public override void SetUp()
        {
            base.SetUp();
            stringValue = default(string);
            integerValue = default(int);
            decimalValue = default(decimal);
            dateTimeValue = default(DateTime);
            uniqueIdentifierValue = default(Guid);
            xmlValueAsString = default(string);
        }

        private class ParameterValueImplementation : Domain.Infrastructure.ParameterValue
        {
            public ParameterValueImplementation(IDefinition definition, IParameter parameter) : base(definition, parameter) { }
        }

        protected void CreateParameterValue(ParameterType type)
        {
            ParameterValue = new ParameterValueImplementation(StubsBuilder.BuildDeploymentDefinitionStub(), StubsBuilder.BuildParameterStub(type: type));
        }

        protected IParameterValue CreateAnotherParameterValue()
        {
            return new ParameterValueImplementation(StubsBuilder.BuildDeploymentDefinitionStub(), ParameterValue.Parameter);
        }

        public virtual void SetStringValue() 
        {
            ParameterValue.StringValue = StringValue;
        }

        public virtual void GetStringValue()
        {
            stringValue = ParameterValue.StringValue;
        }

        public virtual void SetIntegerValue()
        {
            ParameterValue.IntegerValue = IntegerValue;
        }

        public virtual void GetIntegerValue()
        {
            integerValue = ParameterValue.IntegerValue;
        }

        public virtual void SetDecimalValue()
        {
            ParameterValue.DecimalValue = DecimalValue;
        }

        public virtual void GetDecimalValue()
        {
            decimalValue = ParameterValue.DecimalValue;
        }

        public virtual void SetDateTimeValue()
        {
            ParameterValue.DateTimeValue = DateTimeValue;
        }

        public virtual void GetDateTimeValue()
        {
            dateTimeValue = ParameterValue.DateTimeValue;
        }

        public virtual void SetBooleanValue()
        {
            ParameterValue.BooleanValue = BooleanValue;
        }

        public virtual void GetBooleanValue()
        {
            booleanValue = ParameterValue.BooleanValue;
        }

        public virtual void SetUniqueIdentifierValue()
        {
            ParameterValue.UniqueIdentifierValue = UniqueIdentifierValue;
        }

        public virtual void GetUniqueIdentifierValue()
        {
            uniqueIdentifierValue = ParameterValue.UniqueIdentifierValue;
        }

        public virtual void SetXmlValue()
        {
            XmlDocument document = new XmlDocument();
            document.LoadXml(XmlValueAsString);
            ParameterValue.XmlValue = document;
        }

        public virtual void GetXmlValue()
        {
            xmlValueAsString = ParameterValue.XmlValue.OuterXml;
        }

        [Test, ExpectedException(typeof(InvalidActionException))]
        public void CopyTo_ParameterValueForAnotherParameter_ShouldThrowException()
        {
            var anotherDefinition = StubsBuilder.BuildDeploymentDefinitionStub();
            var anotherParameter = StubsBuilder.BuildParameterStub();
            var anotherParameterValue = new ParameterValueImplementation(anotherDefinition, anotherParameter);

            ParameterValue.CopyTo(anotherParameterValue);
        }

        public abstract void CopyTo_ParameterValueForSameParameter_ShouldSucceed();
    }
}
